import random

from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.views import APIView

from celery_tasks.sms.tasks import send_sms_code
from verifications.constants import SMS_CODE_EXPIRES, SMS_FLAG_EXPIRES

"""
由于发送短信与用户模型类无关,不需要对用户模型操作数据库增删改查,因此不采用GenericAPIView,而是采用APIView
url('^sms_code/(?P<mobile>1[3-9]\d{9})/$', views.SMSCodeView.as_view()),
"""
class SMSCodeView(APIView):
    # 发送短信验证码
    def get(self, request, mobile):
        # 1. 限制60秒内只向一个手机号发送一次短信验证码
        # 1.1 获取redis连接,从配置中cache处,根据名称获取连接
        redis_cli = get_redis_connection('sms_code')  # get_redis_connection(): Helper used for obtaining a raw redis client
        # 1.2 60秒判断
        if redis_cli.get('sms_flag_'+mobile):
            raise serializers.ValidationError("请求频繁发送短信")
        # 2 未发送短信,则发送
        # 2.1 生成6位数随意验证码
        code = "%06d" % random.randint(0, 999999)
        print(code)
        # 2.2 将验证码和发送标记保存到redis   键  时长   值
        # redis_cli.setex("sms_code_" + mobile, SMS_CODE_EXPIRES, code)
        # redis_cli.setex("sms_flag_" + mobile, SMS_FLAG_EXPIRES, 1)
        # 由于上述与redis交互两次,因此这里采取redis中的pipeline()方法一次提交
        redis_pipeline = redis_cli.pipeline()
        redis_pipeline.setex("sms_code_" + mobile, SMS_CODE_EXPIRES, code)
        redis_pipeline.setex("sms_flag_" + mobile, SMS_FLAG_EXPIRES, 1)
        redis_pipeline.execute()
        # # 2.3 利用云通讯发送短信
        # CCP.sendTemplateSMS(mobile, code, SMS_CODE_EXPIRES/60, 1)
        # 由于发送短信是独立代码,故使用celery一部任务发送短信,使得耗时代码分开执行
        send_sms_code.delay(mobile, code, SMS_CODE_EXPIRES/60, 1)
        return Response({'message': "OK"})

